package com.qire.common.constant;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.qire.antsrouter.AntsRouter;
import com.qire.antsrouter.card.FloorCard;
import com.qire.common.basic.DateUtil;
import com.qire.common.dal.base.ServiceTimer;
import com.qire.common.utils.CacheStorageUtil;
import com.qire.common.utils.Logger;
import com.qire.common.utils.NoticeEventBus;
import com.qire.common.utils.ToastHelper;

import androidx.annotation.NonNull;

/**
 * 青少年模式管理
 */
public final class TeensModeManage {

    private static final TeensTaskTimer TaskTimer = new TeensTaskTimer();

    private TeensModeManage() {
        throw new UnsupportedOperationException("不能初始化这个管理器");
    }

    /** 青少年模式状态 true:开启 false:关闭 */
    private static boolean TeensModeEnable = false;

    public static void updateReadLimitTime(int readLimitTime) {
        TaskTimer.readLimitTime = readLimitTime;
    }

    /**
     * 更新青少年模式状态
     * @param enable true 开启  false 关闭
     */
    public static void updateTeensModeEnable(boolean enable) {
        TeensModeEnable = enable;
        NoticeEventBus.NOTICE.sendEvent(CustomEvent.TEENS_MODE_STATE);

        TaskTimer.checkTeensOutTimeState();
    }

    /**
     * 解锁授权一次继续使用
     */
    public static void authorizeContinue() {
        TaskTimer.resetReadTimeOut();
        TaskTimer.checkTeensOutTimeState();
        ToastHelper.showCenterDarkToast("", String.format("当前时间锁解锁成功，可继续阅读%s分钟", TaskTimer.readLimitTime));
    }

    /**
     * 返回当前青少年模式状态
     * @return true 开启  false 关闭
     */
    public static boolean teensModeEnable() {
        return TeensModeEnable;
    }

    /**
     * 检查是否青少年可见管制，如果需要的话
     * @param isTeensVisible 漫画是否青少年可见
     * @return true 可见  false 不可见
     */
    public static boolean checkVisibleIfNeed(boolean isTeensVisible) {
        if(TeensModeEnable) {
            return isTeensVisible;
        }
        return true;
    }

    /**
     * 检查页面跳转是否拦截
     * @return true 需要拦截 false 不拦截
     */
    public static boolean gotoPageInterrupt() {
        // 青少年模式开启并且非阅读时间内，需要拦截
        if(TeensModeEnable && !TaskTimer.isReadTime()) {
            return true;
        }
        // 青少年模式开启并且在阅读时间内，如果超时需要拦截，未超时不拦截
        if(TeensModeEnable && TaskTimer.isReadTime() && TaskTimer.checkReadTimeOut()) {
            return true;
        }
        return false;
    }

    private static class TeensTaskTimer extends Handler {
        /** 检查阅读时间的行为 */
        private final int CHECK_READ_TIME_ACTION = 1;

        /** 青少年模式阅读限制时间 */
        private int readLimitTime = 2;
        /** 青少年模式开启时间 */
        private long initialTime = -1;

        private TeensTaskTimer() {
            // 需要指定handler是主线程的，否则在一些机型上会应该静态对象声明发生在子线程而导致异常闪退
            super(Looper.getMainLooper());
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case CHECK_READ_TIME_ACTION:
                    // 检查阅读超时状态
                    checkTeensOutTimeState();
                    break;
                default:
                    throw new RuntimeException("Unknown message " + msg);
            }
        }

        /**
         * 检查青少年模式超时状态
         */
        public synchronized void checkTeensOutTimeState() {
            removeMessages(CHECK_READ_TIME_ACTION);
            if(TeensModeEnable) {
                // 青少年模式启用状态
                if(isReadTime()) {
                    // 阅读时间
                    if(checkReadTimeOut()) {
                        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.TeensLockTimeoutPage).go();
                    } else {
                        sendEmptyMessageDelayed(CHECK_READ_TIME_ACTION, 5000);
                    }
                } else {
                    // 睡眠时间
                    AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.TeensLockSleepPage).go();
                    resetReadTimeOut();
                }
            } else {
                // 青少年模式关闭状态
                resetReadTimeOut();
            }
        }

        /**
         * 是否在阅读事件段内
         * @return
         */
        public boolean isReadTime() {
            return DateUtil.Hm.nowTimeAtBetween("06:00", "22:00");
        }

        /**
         * 检查阅读时间是否超时
         * @return true超时 false 未超时
         */
        public boolean checkReadTimeOut() {
            long currentTime = ServiceTimer.serviceCurrentTime();
            // 1.检查是否存在起始时间，如果不存在则插入当前时间，如果存在则保存起始时间
            initialTime = initialTime > 0 ? initialTime : CacheStorageUtil.queryLong(CacheStorageKey.TEENS_READ_TIME_OUT, -1);
            if(initialTime < 0) {
                initialTime = currentTime;
                CacheStorageUtil.save(CacheStorageKey.TEENS_READ_TIME_OUT, initialTime);
            }
            // 2.检查是否跨天,只需要检查是否跨天，因为如果跨天后在睡眠时间段不会进入这个检查逻辑
            boolean isSameDay = DateUtil.calcTimeDiff(initialTime, currentTime).assertValid(1, true);
            if(!isSameDay) {
                initialTime = currentTime;
                CacheStorageUtil.save(CacheStorageKey.TEENS_READ_TIME_OUT, initialTime);
            }
            // 3.检查是否超时
            long runtime = currentTime - initialTime;
            long limitRuntime = (readLimitTime * 60 * 1000);
            Logger.d(String.format("TeensMode checkReadTimeOut:::::::::::::起始时间：%s, 当前时间：%s, 运行时间:%s, 运行限制时间：%s",
                    initialTime, currentTime, runtime, limitRuntime));
            return runtime > limitRuntime;
        }

        /**
         * 重置阅读超时时间
         */
        public void resetReadTimeOut() {
            CacheStorageUtil.removeKey(CacheStorageKey.TEENS_READ_TIME_OUT);
            initialTime = -1;
        }
    }

}
